#ifndef AODV_RREQ_H
#define AODV_RREQ_H

#include "aodv_types.h"
#include "aodv_routing_table.h"
#include <stdint.h>

// RREQ 处理相关的常量
#define RREQ_WAIT_TIME 2000  // RREQ 等待时间（毫秒）
#define RREQ_RETRIES 3       // RREQ 重试次数
#define RREQ_ID_CACHE_SIZE 100 // RREQ ID 缓存大小（用于防止重复处理）

// RREQ ID 缓存条目结构
typedef struct {
    uint32_t orig_addr;  // 源地址
    uint32_t rreq_id;    // RREQ ID
    uint32_t timestamp;  // 时间戳
} rreq_id_cache_entry;

// RREQ ID 缓存结构
typedef struct {
    rreq_id_cache_entry entries[RREQ_ID_CACHE_SIZE];
    int count;
} rreq_id_cache;

// 初始化 RREQ ID 缓存
void rreq_id_cache_init(rreq_id_cache *cache);

// 检查 RREQ ID 是否已存在（防止重复处理）
int rreq_id_cache_contains(rreq_id_cache *cache, uint32_t orig_addr, uint32_t rreq_id);

// 添加 RREQ ID 到缓存
void rreq_id_cache_add(rreq_id_cache *cache, uint32_t orig_addr, uint32_t rreq_id);

// 生成新的 RREQ ID
uint32_t generate_rreq_id(void);

// 处理接收到的 RREQ 消息
// 参数：
//   rreq - 接收到的 RREQ 消息
//   source_ip - 发送 RREQ 的节点的 IP 地址
//   routing_table - 本地路由表
//   rreq_cache - RREQ ID 缓存
//   local_ip - 本地节点的 IP 地址
// 返回值：
//   0 - 成功处理
//  -1 - 处理失败
int process_rreq_message(const aodv_rreq *rreq, uint32_t source_ip, 
                        aodv_routing_table *routing_table, 
                        rreq_id_cache *rreq_cache, uint32_t local_ip);

// 生成并发送 RREQ 消息
// 参数：
//   dest_addr - 目标地址
//   dest_seq_num - 目标序列号（如果已知）
//   local_ip - 本地节点的 IP 地址
//   socket - 用于发送的 socket
//   routing_table - 本地路由表
// 返回值：
//   0 - 成功发送
//  -1 - 发送失败
int send_rreq(uint32_t dest_addr, uint32_t dest_seq_num, uint32_t local_ip, 
              int socket, aodv_routing_table *routing_table);

// 检查是否需要转发 RREQ
// 根据 RFC 3561，RREQ 应该被转发，除非：
// 1. 当前节点是目标节点
// 2. 当前节点有到目标节点的有效路由且序列号足够新
// 3. RREQ 已经被处理过（通过 RREQ ID 缓存检查）
int should_forward_rreq(const aodv_rreq *rreq, uint32_t local_ip, 
                       aodv_routing_table *routing_table, rreq_id_cache *rreq_cache);

// 转发 RREQ 消息
int forward_rreq(const aodv_rreq *rreq, uint32_t local_ip, int socket);

// 生成 RREP 作为对 RREQ 的响应（当当前节点是目标节点或有有效路由时）
int generate_rrep_for_rreq(const aodv_rreq *rreq, uint32_t local_ip, 
                           aodv_routing_table *routing_table, int socket);

#endif // AODV_RREQ_H